v0.6.60: copilot security improvements, slack canvas ops, retention jobs fixes#4308
v0.6.60: copilot security improvements, slack canvas ops, retention jobs fixes#4308icecrasher321 merged 5 commits intomainfrom
Conversation
icecrasher321
commented
Apr 27, 2026
- fix(security): patch copilot tool & multipart upload IDORs (fix(security): patch copilot tool & multipart upload IDORs #4304)
- fix(stream): Avoid bun memory leak bug from TransformStream (Avoid bun memory leak bug from TransformStream #4255)
- feat(slack): canvas related operations (feat(slack): canvas related operations #4306)
- improvement(slack): channel selector for list canvases (improvement(slack): channel selector for list canvases #4307)
- fix(retention-job): add chunking strategy for cleanup (fix(retention-job): add chunking strategy for cleanup #4305)
* fix(security): patch copilot tool & multipart upload IDORs - multipart upload: bind upload session to (userId, workspaceId, key) via short-lived HMAC-signed token; require workspace write access at initiate; source key/uploadId/context from verified token (never client) at get-part-urls/complete/abort - copilot knowledge-base tools: gate all 11 read/write/tag/connector ops with checkKnowledgeBaseAccess / checkKnowledgeBaseWriteAccess - copilot user-table tools: add workspace-id check to get, get_schema, add/rename/delete/update_column to match existing op pattern - copilot manage-credential: add full ownership/write-permission auth via getCredentialActorContext (previously had no auth) - copilot restore-resource: verify workspace ownership and write permission for workflow, table, knowledgebase, file, and folder restores - copilot folder rename/move: verify both folderId and parentId belong to the caller's workspace via new verifyFolderWorkspace helper - copilot get-job-logs: verify schedule belongs to caller's workspace * fix(security): address PR review — document IDOR, log count, token split - knowledge-base delete_document/update_document: verify each document belongs to the claimed knowledgeBaseId via checkDocumentWriteAccess (was: trusted args.knowledgeBaseId without binding it to the document) - multipart batch complete: log verifiedEntries.length instead of raw client-supplied data.uploads.length - upload-token: reject tokens with !=2 dot-delimited segments * fix(security): close folder workspace bypass when workspaceId is falsy
* Avoid bun memory leak bug from TransformStream * fix(executor): skip content persistence when stream consumer exits early Previously, if the onStream consumer caught an internal error without re-throwing, the block-executor would treat the shortened accumulator as the complete response, persist a truncated string to memory via appendToMemory, and set it as executionOutput.content. Track whether the source ReadableStream actually closed (done=true) in the pull handler. If onStream returns before the source drains, skip content persistence and log a warning — the old tee()-based flow was immune to this because the executor branch drained independently of the client branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix lint * fix(executor): early-return when no streamed content to make onFullContent symmetric Previously, executionOutput.content was guarded by `if (fullContent)` but `onFullContent` fired regardless. The agent-handler implementor defensively bails on empty/whitespace content, but that's a callee contract, not enforced at the call site — future implementors could spuriously persist empty assistant turns to memory. Hoist the `!fullContent` check to a single early return, so both the output write and the callback share the same precondition. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(slack): canvas related operations * extract shared code
* fix(retention-job): add chunking strategy for cleanup * change stats to be perjob not per chunk
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryHigh Risk Overview Copilot/tool access fixes: Adds stricter workspace scoping and write checks across copilot tools (credential manage, restore resource, job logs, knowledge base ops, table ops, workflow folder mutations) to avoid cross-workspace access. Retention + executor improvements: Cleanup jobs now use new chunked SELECT/DELETE utilities ( Slack canvases: Adds new Slack canvas operations ( Reviewed by Cursor Bugbot for commit 65e17de. Configure here. |
Greptile SummaryThis release patches several IDOR vulnerabilities in the copilot tools and multipart upload API, refactors cleanup jobs to chunk large workspace ID lists (avoiding Postgres statement timeouts), replaces Confidence Score: 4/5Safe to merge; security fixes are well-implemented and the one functional gap (list_canvases channel filter) is non-critical. All findings are P2; security patches are thorough with no observed regressions. The only issue is the missing channel wiring for list_canvases, which is a feature gap not a breakage. apps/sim/blocks/blocks/slack.ts — list_canvases case is missing the channel parameter wiring. Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant MultipartAPI as /api/files/multipart
participant TokenModule as upload-token.ts
participant Storage as S3/Blob
Client->>MultipartAPI: POST ?action=initiate {fileName, workspaceId, context}
MultipartAPI->>MultipartAPI: getUserEntityPermissions(userId, workspace)
MultipartAPI->>Storage: initiateMultipartUpload()
Storage-->>MultipartAPI: {uploadId, key}
MultipartAPI->>TokenModule: signUploadToken({uploadId, key, userId, workspaceId, context})
TokenModule-->>MultipartAPI: uploadToken (HMAC-signed)
MultipartAPI-->>Client: {uploadId, key, uploadToken}
Client->>MultipartAPI: POST ?action=get-part-urls {uploadToken, partNumbers}
MultipartAPI->>TokenModule: verifyUploadToken(uploadToken)
TokenModule-->>MultipartAPI: payload (userId, key, uploadId, context)
MultipartAPI->>MultipartAPI: assert payload.userId === session.userId
MultipartAPI->>Storage: getPartUrls(key, uploadId, partNumbers)
Storage-->>MultipartAPI: presignedUrls
MultipartAPI-->>Client: {presignedUrls}
Client->>Storage: PUT parts directly via presigned URLs
Client->>MultipartAPI: POST ?action=complete {uploadToken, parts}
MultipartAPI->>TokenModule: verifyUploadToken(uploadToken)
MultipartAPI->>Storage: completeMultipartUpload(key, uploadId, parts)
Storage-->>MultipartAPI: {location, path, key}
MultipartAPI-->>Client: {success, location, path, key}
Reviews (1): Last reviewed commit: "fix(retention-job): add chunking strateg..." | Re-trigger Greptile |